﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Text;
using ProxyTool.Models;
using ProxyTool.Setting;
using RestSharp;

namespace ProxyTool.Services
{
    internal static class ServiceHelper
    {
        public const string ContextName = "context";

        /// <summary>
        ///     静态请求
        /// </summary>
        /// <param name="serviceAddress"></param>
        /// <param name="serviceAction"></param>
        /// <param name="serviceActionName"></param>
        /// <param name="jsonBody"></param>
        /// <param name="headerDict"></param>
        /// <returns></returns>
        public static T DoRequest<T>(string serviceAddress, string serviceAction,
            string serviceActionName, object jsonBody = null,
            Dictionary<string, string> headerDict = null)
        {
            if (string.IsNullOrEmpty(serviceAddress))
                throw new ArgumentException("服务地址不能为空", "serviceAddress");
            var client = GetRestClient(serviceAddress);
            var request = GetRestRequest(serviceAction);
            if (headerDict != null && headerDict.Count > 0)
            {
                foreach (var key in headerDict.Keys)
                {
                    request.AddHeader(key, headerDict[key]);
                }
            }
            if (jsonBody != null)
                request.AddJsonBody(jsonBody);
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var response = client.Execute<ReturnMessage<T>>(request);
            stopwatch.Stop();
            decimal elapsedSecond = stopwatch.ElapsedMilliseconds/1000L;
            var flag = !string.IsNullOrEmpty(response.ErrorMessage);
            if (flag || response.ResponseStatus == ResponseStatus.Error)
            {
                throw new ServiceException(serviceActionName,
                    response.ErrorMessage + string.Format(" 执行时间: {0} ms", elapsedSecond.ToString("F3")));
            }
            if (response.ResponseStatus == ResponseStatus.TimedOut)
            {
                throw new ServiceException(serviceActionName,
                    string.Format("请求超时,超时时间: {0} ms", elapsedSecond.ToString("F3")));
            }
            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new ServiceException(serviceActionName,
                    response.StatusDescription + string.Format(" 执行时间: {0} ms", elapsedSecond.ToString("F3")));
            }
            if (response.Data == null)
            {
                throw new ServiceException(serviceActionName,
                    "返回信息为空");
            }
            if (!response.Data.IsSuccess)
            {
                throw new ServiceException(serviceActionName,
                    response.Data.ErrMsg + string.Format(" 执行时间: {0} ms", elapsedSecond.ToString("F3")),
                    response.Data.StackString);
            }
            return response.Data.Data;
        }

        /// <summary>
        ///     获取请求
        /// </summary>
        /// <returns></returns>
        private static RestRequest GetRestRequest(string serviceUrl)
        {
            var request = new RestRequest(serviceUrl, Method.POST);
            request.RequestFormat = DataFormat.Json;
            request.JsonSerializer = NewSimpleJsonSerializer.Default;
            return request;
        }

        /// <summary>
        ///     获取RestClient
        /// </summary>
        /// <returns></returns>
        private static RestClient GetRestClient(string serverAdress)
        {
            var client = new RestClient(serverAdress);
            client.Timeout = 60*1000;
            client.ReadWriteTimeout = 60*1000;
            client.AddHandler("application/json", NewSimpleJsonSerializer.Default);
            client.AddHandler("text/json", NewSimpleJsonSerializer.Default);
            client.AddHandler("text/x-json", NewSimpleJsonSerializer.Default);
            client.AddHandler("text/javascript", NewSimpleJsonSerializer.Default);
            client.AddHandler("*+json", NewSimpleJsonSerializer.Default);
            return client;
        }
    }
}